home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 22 / macformat_22.iso / Shareware / Programación / enteract-377 / enteract-377.sit / EnterAct Stuff / write your own Drag_on / CodeResource_Helper.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-22  |  25.0 KB  |  4 lines  |  [TEXT/KEEN]

  1. CodeResource_Helper.cTEXTKEEN^DÊ´Ëò´ËòÅÅ˙/* CodeResource_Helper.c - some handy functions for this and that *//* Copyright not bothered with - this is pretty standard stuff. */#include "CodeResource.h"#include <stdlib.h>/* Resources */short OpenOrCreateResourceFork(StringPtr fileName);void DeleteAllExistingRsrcs(long theType, short theNum);/* Dialogs */void GetDlogOrigin (short dlogID, Point *where);Boolean GetAndAlignDialog(short  resID);void FrameDialogItem(DialogPtr theDP,short theItem);void SetEText(DialogPtr dPtr, short theItem, StringPtr newStr);void GetEText(DialogPtr dPtr, short theItem, StringPtr currentStr);void SetCheck(DialogPtr dPtr, short chkItem, short zeroMeansNoCheck);void GetCheck(DialogPtr dPtr, short chkItem, Boolean *trueIfChecked);Handle GetButton(DialogPtr dPtr, short btnItem);void HiliteDlgControl(DialogPtr dPtr, short btnItem, short state);/* Pascal strings */void CopyPStr(Byte *srcStr, Byte *dstStr);void AppendPStr(Byte *s1, Byte *s2);Boolean PEqualStrs(Byte *aStr, Byte *bStr);/* Files, names and locations */Byte *FullPathNameFromDirectory(long DirID, short vRefNum, Byte *s);Byte *FullPathNameFromVRefNum(short vRefNum, Byte *s);short    OpenWorkingDirectoryFromFullName(char *name, short len);/* Memory allocation */void InitTempCodeMemory(void);void *TMalloc(size_t size);void *Trealloc(void *ptr, size_t size);void Tfree(void *ptr);void TFreeAll(void);/* more memory allocation - faster, more efficient version */void *Fmalloc(register size_t nbytes);static void morecore(register short bucket);static void *true_get_memory(size_t size);void Ffree(void *cp);void *Frealloc(void *cp, size_t nbytes);static short findbucket(union overhead *freep, short srchlen);void FFreeAll(void);/* Misc */void NullOut(char *str, long nBytes);Boolean TaskWasInterrupted(void);Boolean CheckInWithCallingApp(void);/* Resources *//* Returns nonzero refnum if successful */short OpenOrCreateResourceFork(StringPtr fileName)    {    short refNum;        if ((refNum = OpenResFile(fileName)) != -1 && refNum        && ResError() == noErr) /* perfect paranoia */        return(refNum);    else        {        CreateResFile(fileName);        if (ResError() != noErr)            return(0);        if ((refNum = OpenResFile(fileName)) != -1 && refNum            && ResError() == noErr)            return(refNum);        }    return(0);    }/* Delete all instances of a particular resource.Call before creating each resource. */void DeleteAllExistingRsrcs(long theType, short theNum)    {    Handle        rsrcHdle;        while (rsrcHdle = Get1Resource(theType, theNum))        {        RmveResource(rsrcHdle);        DisposHandle(rsrcHdle);        }    }/* Dialogs */void GetDlogOrigin (short dlogID, Point *where)    {    short     screenWidth = GetScreenWidth();    short     screenHeight = GetScreenHeight();    register DialogTHndl dlogHandle;    register Rect * drp;    register short     dlogWidth, dlogHeight;    /* Get a handle to the dialog */    dlogHandle = (DialogTHndl) GetResource ('DLOG', dlogID);    if (!dlogHandle)        {        SetPt (where, 85, 85);        return;        }    /* get pointer to its bounding rectangle */    drp = &((**dlogHandle).boundsRect);    dlogWidth = drp->right - drp->left;    dlogHeight = drp->bottom - drp->top;    /* Calculate upper left corner that will leave box centered */    where->h = (screenWidth - dlogWidth) >> 1;    where->v = (screenHeight - dlogHeight) >> 1;    }Boolean GetAndAlignDialog(short  resID)    {    short            sW,sH,dW,dH,left;    Rect        *drp;    DialogTHndl    dlogHandle;    Boolean        bigScreen;        if (!GetResource('DLOG', resID)        || !GetResource('DITL', resID)        || ResError())        {        MemoryAlert();        return(FALSE);        }    sW = GetScreenWidth();    sH = GetScreenHeight();    dlogHandle = (DialogTHndl) GetResource('DLOG', resID);    drp = &((**dlogHandle).boundsRect);    dW = drp->right - drp->left;    dH = drp->bottom - drp->top;    left = (sW - dW)>>1;    /* all dialogs centered left-right */    drp->left = left;    drp->right = left + dW;    /* vertical placement depends on screen size */    if (sW >= 640 && sH >= 480)        bigScreen = TRUE;    else        bigScreen = FALSE;        if (bigScreen)        {        /* leave one-third of white at top */        drp->top = (sH - dH) / 3;        if (drp->top < 85)            {            if (drp->top < 40)                drp->top = 40;            if (sH <= 85 + dH)                drp->top = 85;            }        }    else if (sH <= 85 + dH)        drp->top = 85;    else        drp->top = 40;    drp->bottom = drp->top + dH;    return(TRUE);    }/* Place thick border around default item in a dialog */void FrameDialogItem(DialogPtr dPtr,short theItem)    {    GrafPtr            savePort;    PenState        savePen;    Handle           h;    Rect            theBox;    short                theType, ovalSize;    GetDItem(dPtr,theItem,&theType,&h,&theBox);    GetPort(&savePort);    SetPort(dPtr);    GetPenState(&savePen);    PenNormal();    PenSize(2,2);    InsetRect(&theBox,-3,-3);    ovalSize = (theBox.bottom + 8 - theBox.top) / 2;        FrameRoundRect(&theBox,ovalSize,ovalSize);    SetPenState(&savePen);    SetPort(savePort);    }/* Set text content in a dialog edit field */void SetEText(DialogPtr dPtr, short theItem, StringPtr newStr)    {    short     theType;    Handle     theItemH;    Rect     theBox;    GetDItem(dPtr, theItem, &theType, &theItemH, &theBox);    SetIText(theItemH, newStr);    }/* Get current text in edit field - note storage for the string mustbe allocated by the calling function. */void GetEText(DialogPtr dPtr, short theItem, StringPtr currentStr)    {    short     theType;    Handle     theItemH;    Rect     theBox;    GetDItem(dPtr, theItem, &theType, &theItemH, &theBox);    GetIText(theItemH, currentStr);    }/* Set/clear check for check box or radio button, pass 0/1 or TRUE/FALSE . */void SetCheck(DialogPtr dPtr, short chkItem, short zeroMeansNoCheck)    {    short     theType;    Handle     theItemH;    Rect     theBox;    GetDItem(dPtr, chkItem, &theType, &theItemH, &theBox);    SetCtlValue((ControlHandle)theItemH, zeroMeansNoCheck);    }/* For check boxes and radio buttons, requires address of a Boolean from the call as in GetCheck(dPtr, 3, &myBoolean). *//* Usage tip, to toggle a box doGetCheck (dPtr, chkItem, &myBoolean);SetCheck (dPtr, chkItem, !myBoolean);*/void GetCheck(DialogPtr dPtr, short chkItem, Boolean *trueIfChecked)    {    short     theType;    Handle     theItemH;    Rect     theBox;    GetDItem(dPtr, chkItem, &theType, &theItemH, &theBox);    *trueIfChecked = (GetCtlValue((ControlHandle)theItemH) != 0);    }/* Retrieve ControlHandle for button, in the form of a Handle */Handle GetButton(DialogPtr dPtr, short btnItem)    {    short     theType;    Handle     theItem;    Rect     theBox;    GetDItem(dPtr, btnItem, &theType, &theItem, &theBox);    return(theItem);    }/* Enable (state 0) or disable (state 255) a dialog control */void HiliteDlgControl(DialogPtr dPtr, short btnItem, short state)    {    ControlHandle theButton;        theButton = (ControlHandle) GetButton(dPtr, btnItem);    if ((**theButton).contrlHilite != state)        HiliteControl (theButton, state);    }/* Pascal strings *//* Copy one pascal string to another */void CopyPStr(Byte *srcStr, Byte *dstStr)    {    long   srcLen = srcStr[0];    BlockMove(srcStr, dstStr, srcLen + 1);    }/* Append pascal s2 to pascal s1, avoiding overflow. */void AppendPStr(Byte *s1, Byte *s2)    {    short    s1Len = s1[0];    short    s2Len = s2[0];    if (s1Len + s2Len > 255)        s2Len = 255 - s1Len;    if (s2Len)        {        BlockMove (s2 + 1, s1 + s1Len + 1, s2Len);        s1Len += s2Len;        s1[0] = s1Len;        }    }Boolean PEqualStrs(Byte *aStr, Byte *bStr)    {    short i, lena = aStr[0], lenb = bStr[0];        if (!lena || !lenb || lena != lenb)return(FALSE);    for (i = 1; i <= lena; ++i)        {        if (aStr[i] != bStr[i])            return(FALSE);        }    return(TRUE);    }/* Files, names and locations *//* NOTE the following two functions are based on examples suppliedby Apple on one of their DTS disks - error checking has been added,and these versions are independent of the signed vs unsigned charcontroversy surrounding str255. Byte is defined in MacTypes.hfor THINK C v4. *//* Warning, these calls can fail! And why not? Everything else can... *//* Bug, these two are not for use by unix imitations. *//* Construct "\PDisk:folder1:folder2:...folderN:" where folderNcontains the file of interest. */Byte *FullPathNameFromDirectory(long DirID, short vRefNum, Byte *s)    {    CInfoPBRec    pb;    Byte        directoryName[256];    s[0] = 0;    pb.dirInfo.ioNamePtr = (StringPtr)directoryName;    pb.dirInfo.ioDrParID = DirID;    do         {        pb.dirInfo.ioVRefNum = vRefNum;        pb.dirInfo.ioFDirIndex = -1;        pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;        if (PBGetCatInfo(&pb, FALSE))            {            break;            }        /* Append a colon  */        AppendPStr(directoryName, (Byte *)"\p:");        AppendPStr(directoryName, s);        CopyPStr(directoryName, s);        } while (pb.dirInfo.ioDrDirID != 2);    return(s);    }Byte *FullPathNameFromVRefNum(short vRefNum, Byte *s)    {    WDPBRec    pb;    pb.ioNamePtr = NULL;    pb.ioVRefNum = vRefNum;    pb.ioWDIndex = 0;    pb.ioWDProcID = 0;    if (PBGetWDInfo(&pb,false))        {        s[0] = 0;        return(s);        }    return(FullPathNameFromDirectory(pb.ioWDDirID,pb.ioWDVRefNum,s));    }/* Determine working directory for file based on full path name. */short    OpenWorkingDirectoryFromFullName(char *name, short len)    {    WDPBRec        theParms;    OSErr     IOResult;    char volname[256];    extern void FileError(OSErr theFileErrorNum);        volname[0] = len;    BlockMove(name, volname+1, len);        theParms.ioCompletion = NULL;    theParms.ioVRefNum = 0;    theParms.ioNamePtr = (StringPtr)volname;    theParms.ioWDDirID = 2;    theParms.ioWDProcID = 'ERIK';    if (IOResult = PBOpenWD(&theParms, FALSE)) /* IM IV pg 158 */        {        OKStopAlert("Disk may not be on-line, \or file may have been moved, deleted, or renamed.");        theParms.ioVRefNum = 0;        }    return(theParms.ioVRefNum);    }/* Memory allocation *//* Preamble: at present, code resources fall into two camps; thosethat allocate a few chunks of memory via NewHandle, and those thatallocate many chunks of memory via malloc. For the latter type,the following functions keep track of what memory was allocated,allowing it to be all freed at the end of a run with one callto TFreeAll().To use the functions TMalloc etc  below instead of the standard malloc etc,place these lines in some header which is included in all yourcode resource files (see eg AWK.H), or at the top of each file:extern void *TMalloc(size_t size);extern void *Trealloc(void *ptr, size_t size);extern void Tfree(void *ptr);#define malloc(x) TMalloc(x)#define realloc(x, y) Trealloc(x, y)#define free(x) Tfree(x)- before firing up your code resource, call InitTempCodeMemory()    - see eg InvokeHAWK() in hAWK_Interface.c-- and after your code resource is done, call TFreeAll()    - see eg CleanUpAfterHAWK() in hAWK_Interface.cNOTE InitTempCodeMemory() is called whether using TMalloc() etcor Fmalloc() etc, BUT the FreeAll() functions are different-TFreeAll() for the former, FFreeAll() for the latter.*/#ifdef malloc#undef malloc#undef realloc#undef free#endif malloctypedef struct MemoryLinks    {    struct MemoryLinks *next, *prev;    }MemoryLinks;MemoryLinks    THead;MemoryLinks *THeadPtr /* = {&THead, NULL}*/;void InitTempCodeMemory(void)    {    THeadPtr = &THead;    THeadPtr->next = &THead;    THeadPtr->prev = &THead;    }/* Tracking versions of malloc, realloc, free - the T stands for temp */void *TMalloc(size_t size)    {    MemoryLinks *new, *old;        size += sizeof(MemoryLinks);    if (!(new = (MemoryLinks *)malloc(size)))        return(NULL);    old = THeadPtr->next; /* true next or THead itself */    old->prev = new;    new->next = old;    new->prev = THeadPtr;    THeadPtr->next = new;    return((void *)(new + 1)); /* user doesn't "see" the links */    }void *Trealloc(void *ptr, size_t size)    {    MemoryLinks *retPtr;        if (!ptr)        return(TMalloc(size));    if (!size)        {        Tfree(ptr);        return(NULL);        }    retPtr = ((MemoryLinks *)(ptr)) - 1;    /* allocate MemoryLinks, too */    size += sizeof(MemoryLinks);    retPtr = (MemoryLinks *)realloc(retPtr, size);    if (!retPtr) /* failure, but block is still there */        return(NULL);    (retPtr->prev)->next = (retPtr->next)->prev = retPtr;    return((void *)(retPtr + 1));    }void Tfree(void *ptr)    {    MemoryLinks *out;        if (!ptr) return;    out = ((MemoryLinks *)(ptr)) - 1;    (out->next)->prev = out->prev;    (out->prev)->next = out->next;    free(out);    }/* list wraps around */void TFreeAll(void)    {    MemoryLinks *dump = THeadPtr->next, *nextOne;#ifdef TMEMDEBUG    long    diff;    char    numStr[16];#endif        while (dump != THeadPtr)        {        nextOne = dump->next;        free(dump);        dump = nextOne;        }#ifdef TMEMDEBUG    NumToString(malled, (StringPtr)numStr);    PtoCstr(numStr);    OKStopAlert("Total malloc'd:");    OKStopAlert(numStr);    NumToString(realled, (StringPtr)numStr);    PtoCstr(numStr);    OKStopAlert("Total realloc'd:");    OKStopAlert(numStr);    if (numfreedAtEnd + tfreeNum != tmallocNum)        {        diff = numfreedAtEnd + tfreeNum - tmallocNum;        if (diff < 0L)            {            diff = -diff;            NumToString(diff, (StringPtr)numStr);            PtoCstr(numStr);            OKStopAlert(numStr);            }        else /* very odd - more freed than allocated */            {            NumToString(diff, (StringPtr)numStr);            PtoCstr(numStr);            SysBeep(2);            SysBeep(2);            OKStopAlert(numStr);            }                }    else        {        NumToString(tmallocNum, (StringPtr)numStr);        PtoCstr(numStr);        OKStopAlert("Num malloc calls total:");        OKStopAlert(numStr);        }#endif    }/* more memory allocation - a more efficient (frugal) version *//* A frugal malloc, especially suited for allocating many manysmall blocks of memory. Currently used by hAWK, which is constantly allocating and freeing small blocks. Note TMalloc()above basically uses THINK C's malloc, which suffers fromsevere fragmentation problems. There is also more overhead withTMalloc (8 bytes vs 4 here).Memory is pre–allocated on demand for specific sizes only whichare all powers of two (plus overhead). When you request a blockof memory, your requested size is rounded up to the next powerof two, and the request is satisfied from an array of similar-sized blocks. *//* Modified for the Mac and THINK C by Ken Earle.   Based on Larry Wall’s modification (1989) of: * malloc.c (Caltech) 2/21/82 * Chris Kingsley, kingsley@cit-20. * * This is a very fast storage allocator.  It allocates blocks of a small * number of different sizes, and keeps free lists of each size.  Blocks that * don't exactly fit are passed up to the next larger size.  In this * implementation, the available sizes are 2^n-4 bytes long. * This is designed for use in a program that uses vast quantities of memory, * but bombs when it runs out.To use the functions Fmalloc etc  below instead of the standard malloc etc,place these lines in some header which is included in all yourcode resource files (see eg AWK.H and CodeResHelper.h), or at the top of each file:extern void *Fmalloc(size_t size);extern void *Frealloc(void *ptr, size_t size);extern void Ffree(void *ptr);#define malloc(x) Fmalloc(x)#define realloc(x, y) Frealloc(x, y)#define free(x) Ffree(x)- before firing up your code resource, call InitTempCodeMemory()    - see eg InvokeHAWK() in hAWK_Interface.c-- and after your code resource is done, call FFreeAll()    - see eg CleanUpAfterHAWK() in hAWK_Interface.cNOTE InitTempCodeMemory() is called whether using TMalloc() etcor Fmalloc() etc, BUT the FreeAll() functions are different-TFreeAll() for the former, FFreeAll() for the latter. */#define u_char unsigned char#define u_int unsigned short#define u_short unsigned short/* * The overhead on a block is at least 4 bytes.  When free, this space * contains a pointer to the next free block, and the bottom two bits must * be zero.  When in use, the first byte is set to MAGIC, and the second * byte is the size index.  The remaining bytes are for alignment. */union    overhead {    union    overhead *ov_next;    /* when free */    struct {        u_char    ovu_magic;    /* magic number */        u_char    ovu_index;    /* bucket # */    } ovu;};#define    ov_magic    ovu.ovu_magic#define    ov_index    ovu.ovu_index#define    MAGIC        0xff        /* magic # on accounting info *//* * nextf[i] is the pointer to the next free block of size 2^(i+3).  The * smallest allocatable block is 8 bytes.  The overhead information * precedes the data area returned to the user. */#define    NBUCKETS 30static    union overhead *nextf[NBUCKETS];#ifdef MSTATS/* * nmalloc[i] is the difference between the number of mallocs and frees * for a given block size. */static    u_int nmalloc[NBUCKETS];#endif/* F stands for Frugal */void *Fmalloc(register size_t nbytes)    {    register union overhead *p;    register short bucket = 0;    register size_t shiftr;        /*     * Convert amount of memory requested into     * closest block size stored in hash buckets     * which satisfies request.  Account for     * space used per block for accounting.     */    nbytes += sizeof (union overhead);    nbytes = (nbytes + 3) &~ 3;    shiftr = (nbytes - 1) >> 2;    /* apart from this loop, this is O(1) */    while (shiftr >>= 1)        bucket++;    /*     * If nothing in hash bucket right now,     * request more memory from the system.     */    if (nextf[bucket] == NULL)        morecore(bucket);    if ((p = (union overhead *)nextf[bucket]) == NULL)        return (NULL);    /* remove from linked list */    nextf[bucket] = p->ov_next;    p->ov_magic = MAGIC;    p->ov_index = bucket;#ifdef MSTATS    nmalloc[bucket]++;#endif    return ((void *)(p + 1));    }/* * Allocate more memory to the indicated bucket. */static void morecore(register short bucket)    {    register union overhead *op;    register short rnu;       /* 2^rnu bytes will be requested */    register short nblks;     /* become nblks blocks of the desired size */    register short siz;    if (nextf[bucket])        return;    /* take 16k unless the block is bigger than that */    rnu = (bucket <= 11) ? 14 : bucket + 3;        nblks = 1 << (rnu - (bucket + 3));  /* how many blocks to get */    if (rnu < bucket)        rnu = bucket;    op = (union overhead *)true_get_memory((size_t)(1 << rnu));    /* no more room! */    if (op == NULL)        return;    /*     * Add new memory allocated to that on     * free list for this hash bucket.     */    nextf[bucket] = op;    siz = 1 << (bucket + 3);    while (--nblks > 0) {        op->ov_next = (union overhead *)((char *)op + siz);        op = (union overhead *)((char *)op + siz);    }    op->ov_next = NULL;}/* Allocate a large lump of memory, and remember it in a linkedlist so that it can be disposed later. */static void *true_get_memory(size_t size)    {    MemoryLinks *new, *old;        size += sizeof(MemoryLinks);    if (!(new = (MemoryLinks *)NewPtr((long)size)))        return(NULL);    old = THeadPtr->next; /* true next or THead itself */    old->prev = new;    new->next = old;    new->prev = THeadPtr;    THeadPtr->next = new;    return((void *)(new + 1)); /* user doesn't "see" the links */    }void Ffree(void *cp)    {    register short size;    register union overhead *op;        if (cp == NULL)        return;    op = (union overhead *)((char *)cp - sizeof (union overhead));    if (op->ov_magic != MAGIC) {        return;                /* sanity */    }    size = op->ov_index;    op->ov_next = nextf[size];    nextf[size] = op;#ifdef MSTATS    nmalloc[size]--;#endif    }/* * When a program attempts "storage compaction" as mentioned in the * old malloc man page, it realloc's an already freed block.  Usually * this is the last block it freed; occasionally it might be farther * back.  We have to search all the free lists for the block in order * to determine its bucket: 1st we make one pass thru the lists * checking only the first block in each; if that fails we search * ``reall_srchlen'' blocks in each list for a match (the variable * is extern so the caller can modify it).  If that fails we just copy * however many bytes was given to realloc() and hope it's not huge. */short reall_srchlen = 4;    /* 4 should be plenty, -1 =>'s whole list */void *Frealloc(void *cp, size_t nbytes)    {    register size_t onb;    union overhead *op;    char *res;    register short i;    short was_alloced = 0;    if (cp == NULL)        return (Fmalloc(nbytes));    if (!nbytes)        {        Ffree(cp);        return(NULL);        }    op = (union overhead *)((char *)cp - sizeof (union overhead));    if (op->ov_magic == MAGIC) {        was_alloced++;        i = op->ov_index;    } else {        /*         * Already free, doing "compaction".         *         * Search for the old block of memory on the         * free list.  First, check the most common         * case (last element free'd), then (this failing)         * the last ``reall_srchlen'' items free'd.         * If all lookups fail, then assume the size of         * the memory block being realloc'd is the         * smallest possible.         */        if ((i = findbucket(op, 1)) < 0 &&            (i = findbucket(op, reall_srchlen)) < 0)            i = 0;    }    onb = (1 << (i + 3)) - sizeof (*op);    /* avoid the copy if same size block */    if (was_alloced &&        nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op)) {        return(cp);    }    if ((res = Fmalloc(nbytes)) == NULL)        return (NULL);    if (cp != res)            /* common optimization */        BlockMove ((Ptr)cp, (Ptr)res, (Size)((nbytes < onb) ? nbytes : onb));    if (was_alloced)        Ffree(cp);    return (res);}/* * Search ``srchlen'' elements of each free list for a block whose * header starts at ``freep''.  If srchlen is -1 search the whole list. * Return bucket number, or -1 if not found. */static short findbucket(union overhead *freep, short srchlen)    {    register union overhead *p;    register short i, j;    for (i = 0; i < NBUCKETS; i++) {        j = 0;        for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {            if (p == freep)                return (i);            j++;        }    }    return (-1);    }#ifdef MSTATS/* * mstats - print out statistics about malloc * * Prints two lines of numbers, one showing the length of the free list * for each size category, the second showing the number of mallocs - * frees for each size category. */void mstats(char *s);void mstats(char *s)    {    register short i, j;    register union overhead *p;    short totfree = 0,    totused = 0;    fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);    for (i = 0; i < NBUCKETS; i++) {        for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)            ;        fprintf(stderr, " %d", j);        totfree += j * (1 << (i + 3));    }    fprintf(stderr, "\nused:\t");    for (i = 0; i < NBUCKETS; i++) {        fprintf(stderr, " %d", nmalloc[i]);        totused += nmalloc[i] * (1 << (i + 3));    }    fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",        totused, totfree);    }#endif/* list wraps around */void FFreeAll(void)    {    MemoryLinks *dump = THeadPtr->next, *nextOne;        while (dump != THeadPtr)        {        nextOne = dump->next;        DisposPtr((Ptr)dump);        dump = nextOne;        }    }/* Misc */void NullOut(char *str, long nBytes)    {    register long i;        i = nBytes;    while (--i >= 0)        *str++ = '\0';    }/* Check for the generic "Command<period>" that signals awish to stop. */Boolean TaskWasInterrupted()    {    EventRecord    event;    long        thisTime;    Boolean        gotEvent;    static long    lastTime;        Delay(0L, &thisTime);    if (thisTime - lastTime < 60L) return(FALSE);    lastTime = thisTime;    SystemTask();    gotEvent = GetNextEvent(62, &event);    if (gotEvent) /* see if interrupt */        {        switch (event.what)            {        case keyDown:        case autoKey:            /* look for abort key (Command-<period>) */        if ((event.modifiers & cmdKey)             && ((event.message & charCodeMask) == '.'))            {            return(TRUE);            }        break;        default:        break;            } /* switch */        }    return(FALSE);    }/* Check for events 15 times a second, allow hAWK to run forat most 12 ticks if no event. Return control to callingapp's event loop, so that hAWK can run at the same timeas calling app without too much slowdown. Return TRUEif interrupted, FALSE if should continue. */Boolean CheckInWithCallingApp()    {    EventRecord    event;    long        thisTime;    Boolean        gotEvent;    static long    lastTime, tickAlong;        Delay(0L, &thisTime);    if (thisTime < tickAlong) return(FALSE);    tickAlong = thisTime + 4L;        if ((gotEvent = EventAvail(everyEvent, &event))        || thisTime - lastTime > 12L)        {        if (gotEvent)            {            switch (event.what)                {            case keyDown:            case autoKey:                /* look for abort key (Command-<period>) */            if ((event.modifiers & cmdKey)                 && ((event.message & charCodeMask) == '.'))                {                GetNextEvent(62, &event);                return(TRUE);                }            break;            default:            break;                } /* switch */            }        else            lastTime = thisTime;        DoEventLoopOnce();        }    return(FALSE);    }XXéHelper.c - some handy functions CodeResource_Helper.cTEXTKETEXTKEEN4§ƒ≠ª^DÊan replace thethree calls above to stringLength() with strlen().*/long stringLength(char *s)    {    long        len = 0L;        while (*s++
  2.     Monaco´°∑2,‡fi!_i AppendPStr[Ç[óCheckInWithCallingApp±π    CopyPStr    S    iDeleteAllExistingRsrcsV≠Vµ    FFreeAllHúH°Ffree?÷?›Fmalloc&FrameDialogItemL•L≠    FreallocgÄFullPathNameFromDirectory!û!µFullPathNameFromVRefNumR:RD findbucket GetAndAlignDialogñü    GetButtonYa    GetCheck
  3. %
  4. 2GetDlogOriginRZ    GetETextâôHiliteDlgControl*œ*·InitTempCodeMemoryCrCz    morecoreT[TamstatsWjWqNullOuttåOpenOrCreateResourceFork##&!OpenWorkingDirectoryFromFullNameV` PEqualStrszÇ    SetCheck    SetETextX(X:TaskWasInterrupted/|/Ñ    TFreeAll.∞.µTfree+Ü+çTMalloc,‰,Ï    TreallocG1G@true_get_memoryH    Monaco*˝˝8ˆ|´¢N*9XXé_å 4éETAB*EFNT6JAGZBWSIZNMPSRZÏˇˇΡˇÌˇˇÓˇˇÔˇˇ*Ìˇˇ